using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using ICSharpCode.SharpZipLib.Zip;
using Yoozoo.Core.Extensions.CSharp;
using Yoozoo.External.LZ4;
using Yoozoo.Libs;
using Yoozoo.Managers.NetworkV2.DataStruct;
using Yoozoo.Managers.NetworkV2.Helpers;

namespace Yoozoo.Framework.Network.Helpers
{
    public class GTAPacketDeserializerHelper :  IPacketHeaderHelper, IPacketBodyHelper
    {
        
        private const int CS_PACKAGE_RECIVE_HEAD_LENGTH = 10;

        public int PackageHeaderLength => 4;
        
        //private readonly MemoryStream m_DeserializeCachedStream = new MemoryStream(1024 * 8);
        
        public IPacketHeader DeserializeHeader(Stream source, out object customErrorData)
        {
            customErrorData = null;
            
            byte[] totalLengthBytes = new byte[4];
            source.Read(totalLengthBytes, 0, 4);
            int totalLength = Converter.GetBigEndian(BitConverter.ToInt32(totalLengthBytes,0)) + CS_PACKAGE_RECIVE_HEAD_LENGTH;

            var header = new BasicPacketHeader
            {
                PacketLength = totalLength,
                HeaderByteLength = PackageHeaderLength
            };
            return header;
        }
        /// <summary>
        /// 解包体； 解压缩、验证下型号是否正确
        /// </summary>
        /// <param name="header"></param>
        /// <param name="source"></param>
        /// <param name="customErrorData"></param>
        /// <returns></returns>
        public IPacket DeserializePacketCore(IPacketHeader header, Stream source, out object customErrorData)
        {
            customErrorData = null;
            #region 解析
            
            MemoryStream ms = source as MemoryStream;
            byte[] bytes = ms.ToArray();
            int msgLen = header.PacketLength;
            
            //消息索引序号
            int offset = 0;
            int sn = Converter.GetBigEndian(BitConverter.ToInt32(bytes, offset));
            offset += 4;
            
            //消息ID
            ushort msgId = Converter.GetBigEndian(BitConverter.ToUInt16(bytes, offset));
            offset += 2;
            
            //解压后包体长度
            int decodeLen = Converter.GetBigEndian(BitConverter.ToInt32(bytes, offset));
            offset += 4;
            
            //tracerId是否存在的标记
            bool tracerIdExistFlag = BitConverter.ToBoolean(bytes, offset);
            offset += 1;
            
            //tracerId
            string tracerId = string.Empty;
            //tracerId长度
            int tracerIdLen = 16;
            if (tracerIdExistFlag)
            {
                tracerId = Encoding.UTF8.GetString(bytes, offset, tracerIdLen);
                offset += tracerIdLen;
            }

            // Debug.LogWarning($"收到协议：msgLen = {msgLen} sn = {sn} msgId = {msgId} decodeLen = {decodeLen} tracerId = {tracerId}");
            
            msgLen -= offset;
            //解析数据
            byte[] proto = null;
            if (decodeLen == 0)
            {
                int protoLen = msgLen;
                proto = new byte[protoLen];
                Array.Copy(bytes, offset, proto, 0, protoLen);
            }
            else
            {
                int decodeLength = msgLen;
                byte[] outPutBytes = new byte[decodeLen];
                if (LZ4Codec.Decode(bytes, offset, decodeLength, outPutBytes, 0,
                    decodeLen) == decodeLen)
                {
                    proto = outPutBytes;
                }
                else
                {
                    UnityEngine.Debug.LogFormat("<color=red>msgId:{0} sn:{1} LZ4Codec.Decode failed!!!</color>",
                        msgId, sn);
                    
                }
            }

            if (GTAReceivedInfoHelper.CheckMsgAvaliable(sn))
            {
                //在可用的协议中 只记录下行序列号大于0的协议
                if (sn > 0)
                {
                    //下行序列号大于0的协议是我们期望
                    GTAReceivedInfoHelper.UpdateReceivedIndex(sn);
                }
                GTAReceivedInfoHelper.AddReceivedMsgIndexToBuffer(sn,msgId);
            }
            else
            {
                GTAReceivedInfoHelper.PrintReceivedIndex(sn,msgId);
                msgId = 0;
            }
            
            var basicPacket = BasicPacket.Get();
            basicPacket.UpdateData(msgId, tracerId, proto, header);
            return basicPacket;

            #endregion
        }
        

        [Obsolete("接口废弃了，use CSharpNetWorkReciever")]
        public IPacket DeserializePacketContent(IPacket packet, out object customErrorData)
        {
             customErrorData = null;
            // //不为C#侧解析
            // packet.message = packet.rawData;
            //
            // if (packet.rawData != null)
            // {
            //     m_DeserializeCachedStream.SetLength(m_DeserializeCachedStream.Capacity); // 此行防止 Array.Copy 的数据无法写入
            //     m_DeserializeCachedStream.Position = 0L;
            //     m_DeserializeCachedStream.Write(packet.rawData, 0, packet.rawData.Length);
            //     m_DeserializeCachedStream.Position = 0L;
            //     m_DeserializeCachedStream.SetLength(packet.rawData.Length);
            //     // IMessage imessaeg = Activator.CreateInstance(GameFramework.Protocal.GetSCMap(packet.Id)) as IMessage;
            //     // packet.message = imessaeg.Descriptor.Parser.ParseFrom(m_DeserializeCachedStream);
            //     packet.message = default;
            // }
            // else
            // {
            //     packet.message = null;
            // }
            return packet;
         }
    }
}
